/**
 * Created by Wangwei on 2017/1/4.
 */
layui.define(['config', 'common'], function (exports) {
    var _Http = {},
        globalData = {},//全局数据,请求时会发送
        interceptors = []; //全局拦截器;
    var $ =layui.jquery,layer = layui.layer,$setting = layui.config,$util = layui.common;

    /**
     * 合并数据
     * @param global
     * @param data
     * @returns {*}
     */
    function merge(global, data) {

        if (!data) return copy(global, {});

        var result = copy(global, {});

        return copy(data, result);
    }

    /**
     * copy json对象数据
     * @param s 源对象
     * @param t 目的对象
     * @returns {*}
     */
    function copy(source, target) {
        for (var key in source) {
            target[key] = source[key];
        }
        return target;
    }


    /**
     * 将普通数组转化为json对象,tool.json key为数组项值
     * 方便判断
     * @param arr
     * @returns {{}}
     */
    function toJsonArr(arr) {
        var json = {};

        for (var i = 0, total = arr.length; i < total; i++) {
            json[arr[i]] = "";
        }

        return json;
    }

    /**
     * 检测json数组中是否包含某个值
     * @param jsonArr 该值必须是从toJsonArr函数得来的
     * @param val 要检查的值
     * @returns {*|boolean} 结果
     */
    function contain(jsonArr, val) {
        return jsonArr.hasOwnProperty(val);
    }

    function assembleUrl (url) {
        var targetUrl = '';
        if (url.indexOf('http://') === -1 && url.indexOf('https://') === -1) {
            if (url.indexOf('/') === 0) {
                targetUrl = $setting.getUri() + url;
            } else {
                targetUrl = $setting.getUri() + '/' + url;
            }
        } else {
            targetUrl = url;
        }
        var searchUrl = window.location.search;
        if (searchUrl.indexOf('?') >= 0) {
            var paramstr = searchUrl.substring(searchUrl.indexOf('?') + 1);
            if (url.indexOf('?') >= 0) {
                targetUrl = targetUrl + '&' + paramstr;
            } else {
                targetUrl = targetUrl + '?' + paramstr;
            }
        }
        return targetUrl;
    }

    /**
     * Ajax请求对象
     * @param method 请求类型
     * @param url 请求链接
     * @param data 发送的数据  json对象or拼接的string数据
     * @constructor
     */
    var Request = function (method, url, data) {
        this.url = assembleUrl(url);
        this.method = method;
        this.data = data || {};
        this.headers = [];
    };

    /**
     * 设置响应数据类型
     * @param type 字符串"tool.json"/"xml"等
     * @returns {Request}
     */
    Request.prototype.type = function (type) {
        this.type = type;
        return this;
    };

    /**
     * 设置发送的数据，将覆盖已设置的数据
     * @param data  json对象or拼接的string数据
     * @returns {Request}
     */
    Request.prototype.data = function (data) {
        this.data = data;
        return this;
    };

    /**
     * 设置新发送的数据
     * @param key 参数名/tool.json object
     * @param value 参数值
     * @returns {Request}
     */
    Request.prototype.push = function (key, value) {
        if (!key || !value) return;

        try {
            var json = {};
            json[key] = value;
            copy(json, this.data);
        } catch (err) {
            this.data[key] = value;
        }
        return this;
    };

    /**
     * set headers
     * @param  {[json object]} headers
     * @return {[Request]}
     */
    Request.prototype.headers = function (headers) {
        this.headers = headers;
        return this;
    };

    /**
     * push header item
     * @param  {[String,JSON]} key
     * @param  {[String,null]} value
     * @return {[Request]}
     */
    Request.prototype.header = function (key, value) {
        if (!key || !value) return;

        try {
            JSON.stringify(key);
            copy(key, this.headers);
        } catch (err) {
            this.headers[key] = value;
        }
        return this;
    };

    /**
     * execute interceptors
     * @param  {[type]} res [description]
     * @return {[type]}     [description]
     */
    Request.prototype.execuInters = function (res) {
        //执行拦截器
        for (var i = 0, total = interceptors.length; i < total; i++) {
            //先判断是否是所要拦截的数据响应类型
            if (!contain(interceptors[i].type, self.type)) {
                continue;
            }

            var invoke = interceptors[i].fn(res); //执行拦截器
            //检查结果,决定是否继续执行其他拦截器
            if (invoke !== undefined && !invoke) {
                return false;
            }
        }
        return true;
    };

    /**
     * 发送请求
     * @param success 成功响应回调函数
     * @param error 错误处理回调函数
     */
    Request.prototype.send = function (success, error) {
        var self = this;
        var param = {
            url: this.url,
            type: this.method,
            xhrFields: {        //跨域
                withCredentials: true
            },
            crossDomain: true,
            async: this.async===false?false:true
        };

        // 设置响应数据类型
        if (this.type) {
            param.dataType = this.dataType;
            // param.dataType = 'jsonp';
        }

        //设置发送数据
        if (this.data && typeof this.data !== 'function') {
            param.data = this.data;
        }

        //set headers
        if (this.headers && typeof this.headers !== 'function' && JSON.stringify(this.headers).length > 2) {
            param.headers = this.headers;
        }
        //设置成功响应回调函数
        if (success && typeof success === 'function') {
            param.success = function (res) {
                //公共返回处理
                if (res.code == '10000') {  //未登录
                    if(!window.hasAlert) {
                        window.hasAlert = true;
                        // layer.alert('未登录', {
                        //     skin: 'layui-layer-molv' //样式类名
                        //     , closeBtn: 0
                        // }, function () {
                            parent.location.href = $setting.getLocalUri()+'/login.html';
                        // });
                    }

                    return false;
                }
                if (self.execuInters(res)) { //执行回调
                    success(res);
                }
            };
        }

        //设置错误响应回调函数
        if (error && typeof error === 'function') {
            param.error = function (err) {
                //正确的请求响应
                if (err.status === 200 && err.statusText === "OK") {
                    var response = err.responseText;

                    //如果是json数据，则转化为json对象
                    try {
                        response = JSON.parse(response);
                    } catch (parseError) {
                        response = err.responseText;
                    }

                    if (self.execuInters(response)) {//执行回调
                        success(response);
                    }
                } else {
                    error(err);
                }
            };
        }

        var browser = function myBrowser() {
            var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
            var isOpera = userAgent.indexOf("Opera") > -1;
            if (isOpera) {  //判断是否Opera浏览器
                return "Opera"
            }
            if (userAgent.indexOf("Firefox") > -1) {    //判断是否Firefox浏览器
                return "FF";
            }
            if (userAgent.indexOf("Chrome") > -1) {
                return "Chrome";
            }
            if (userAgent.indexOf("Safari") > -1) { //判断是否Safari浏览器
                return "Safari";
            }
            if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera) {   //判断是否IE浏览器
                return "IE";
            }
        };

        // if (browser() == 'FF') {
        //     var xhr = new XMLHttpRequest();
        //     xhr.open(param.type, param.url);
        //     xhr.withCredentials = true;
        //     xhr.async = false;
        //     xhr.onload = function () {
        //         var res = JSON.parse(xhr.responseText);
        //         if (res.code == '10000') {  //未登录
        //             $('body').html('');
        //             location.href = 'login.html';
        //             return false;
        //         }
        //     };
        //     xhr.send();
        // } else {
            $.ajax(param);
        // }
    };

    /**
     * 发送POST请求
     * @param url 请求地址
     * @param data 请求数据，json或拼接的字符串
     * @returns {Request} 请求对象
     */
    _Http.post = function (url, data) {
        return new Request("POST", url, merge(globalData, data));
    };

    /**
     * 发送PUT请求
     * @param url 请求地址
     * @param data 请求数据，json或拼接的字符串
     * @returns {Request} 请求对象
     */
    _Http.put = function (url, data) {
        return new Request("PUT", url, merge(globalData, data));
    };

    /**
     * 发送GET请求
     * @param url 请求地址
     * @param data 请求数据，json或拼接的字符串
     * @returns {Request} 请求对象
     */
    _Http.get = function (url, data) {
        return new Request("GET", url, merge(globalData, data));
    };

    /**
     * 发送DELETE请求
     * @param url 请求地址
     * @param data 请求数据，json或拼接的字符串
     * @returns {Request} 请求对象
     */
    _Http.del = function (url, data) {
        return new Request("DELETE", url, merge(globalData, data));
    };

    /**
     * 设置全局请求值
     * @param name string or jsonObject
     * @param value
     */
    _Http.global = function (name, value) {
        if (!name || !value) return;
        try {
            var json = {};
            json[name] = value;
            copy(json, globalData);
        } catch (err) {
            globalData[name] = value;
        }

        return _Http;
    };

    /**
     * 新增一个拦截器
     * @param type
     * @param fn
     */
    _Http.intercept = function (type, fn) {
        //type参数可以为单个字符串或数组
        if (typeof type === 'string') {
            type = [type];//转化为数组
        }

        interceptors.push({
            type: toJsonArr(type),
            fn: fn
        });

        return _Http;
    };

    _Http.ajaxSubmit = function (form, data, success) {
        var url = assembleUrl(data.url);
        $(form).ajaxSubmit({
            url: url,
            xhrFields: {        // 跨域
                withCredentials: true
            },
            crossDomain: true,
            type: data.method,
            data: data.param,
            success: function (obj) {
                success(obj)
            }
        });
    };
    _Http.bootstrapTable = function (table, data) {
        data.url = assembleUrl(data.url);
        $(table).bootstrapTable(data);
    };

    exports('http', _Http); // 注意，这里是模块输出的核心，模块名必须和use时的模块名一致
});